#include "esp8266.h"

/* 协议文件 */
#include "onenet.h"
#include "mqttkit.h"

/* 硬件驱动 */
//#include "usart.h"
//#include "delay.h"
//#include "led.h"
#include "main.h"

/* C库 */
#include <string.h>
#include <stdio.h>
#include "cjson.h"
#include "OLED.h"
#include "usart.h"
#define PROID		"X89LzWbnsU"

#define AUTH_INFO	"version=2018-10-31&res=products%2FX89LzWbnsU%2Fdevices%2Fsoil&et=2052136032&method=md5&sign=ryt6dF9Ka9eKJf%2FsKelH3A%3D%3D"

#define DEVID		"soil"
#define ONENET_MQTT_PUB_SET "AT+MQTTPUB=0,\"$sys/"


extern unsigned char esp8266_buf[128];
extern unsigned char esp8266_cnt;
uint8_t Uart2_RxData;			/* 接收中断缓冲 */

extern unsigned char humi_max;
extern unsigned char light_max;
uint8_t temperature;  			/* 温度 */
uint8_t humidity;     			/* 湿度 */
int Val;

void OneNET_Publish(const char *topic, const char *msg);

//==========================================================
//	函数名称：	OneNet_DevLink
//
//	函数功能：	与onenet创建连接
//
//	入口参数：	无
//
//	返回参数：	1-成功	0-失败
//
//	说明：		与onenet平台建立连接
//==========================================================


_Bool OneNet_DevLink(void)
{
	
	MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};			/* 协议包 */

	unsigned char *dataPtr;
	
	_Bool status = 1;
	
	printf("OneNet_DevLink\r\n"
							"PROID: %s,	AUIF: %s,	DEVID:%s\r\n"
                        , PROID, AUTH_INFO, DEVID);
	
	if(MQTT_PacketConnect(PROID, AUTH_INFO, DEVID, 256, 1, MQTT_QOS_LEVEL0, NULL, NULL, 0, &mqttPacket) == 0)
	{
	
		ESP8266_SendData(mqttPacket._data, mqttPacket._len);		/* 上传平台 */
		dataPtr = ESP8266_GetIPD(250);					/* 等待平台响应 */

		if(dataPtr != NULL)
		{
			if(MQTT_UnPacketRecv(dataPtr) == MQTT_PKT_CONNACK)
			{
				switch(MQTT_UnPacketConnectAck(dataPtr))
				{
					case 0:printf("Tips:	连接成功\r\n");status = 0;break;
					
					case 1:printf("WARN:	连接失败：协议错误\r\n");break;
					case 2:printf("WARN:	连接失败：非法的clientid\r\n");break;
					case 3:printf("WARN:	连接失败：服务器失败\r\n");break;
					case 4:printf("WARN:	连接失败：用户名或密码错误\r\n");break;
					case 5:printf("WARN:	连接失败：非法链接(比如token非法)\r\n");break;
					
					default:printf("ERR:	连接失败：未知错误\r\n");break;
				}
			}
		}
		
		MQTT_DeleteBuffer(&mqttPacket);		/* 删包 */
	}
	else
		printf("WARN:	MQTT_PacketConnect Failed\r\n");

    HAL_Delay(500);
	return status;
	
}

		
unsigned char OneNet_FillBuf(char *buf)
{
	
	char text[55];
 
	
	strcpy(buf,"{\"id\":\"123\",\"params\":{");

	
	memset(text, 0, sizeof(text));
	sprintf(text,"\"temp\":{\"value\":%d},",temperature);
	strcat(buf, text);
	
	memset(text, 0, sizeof(text));
	sprintf(text,"\"humi\":{\"value\":%d},",humidity);
	strcat(buf, text);
	
	
	memset(text, 0, sizeof(text));
	sprintf(text,"\"val\":{\"value\":%d}",Val);
	strcat(buf, text);
	
	strcat(buf,"}}");
	
	return strlen(buf);

}

//==========================================================
//	函数名称：	OneNet_SendData
//
//	函数功能：	上传数据到平台
//
//	入口参数：	type：发送数据的格式
//
//	返回参数：	无
//
//	说明：		
//==========================================================
void OneNet_SendData(void)
{
	
	MQTT_PACKET_STRUCTURE mqttPacket = {NULL, 0, 0, 0};												//协议包
	
	char buf[128];
	
	short body_len = 0, i = 0;
	
	printf("Tips:	OneNet_SendData-MQTT\r\n");
	
	memset(buf, 0, sizeof(buf));
	
	body_len = OneNet_FillBuf(buf);																	//获取当前需要发送的数据流的总长度
	printf("%s\r\n",buf);
	if(body_len)
	{
		if(MQTT_PacketSaveData(DEVID, body_len, NULL, 5, &mqttPacket) == 0)							//封包
		{
			for(; i < body_len; i++)
			{
		    		mqttPacket._data[mqttPacket._len++] = buf[i];
			}
				
//			printf("%s\r\n",mqttPacket._data);
			ESP8266_SendData(mqttPacket._data, mqttPacket._len);									//上传数据到平台
			printf("Send %d Bytes\r\n", mqttPacket._len);
			
			MQTT_DeleteBuffer(&mqttPacket);															//删包
		}
		else
			printf("WARN:	EDP_NewBuffer Failed\r\n");
	}
	
}

//==========================================================
//	函数名称：	OneNet_RevPro
//
//	函数功能：	平台返回数据检测
//
//	入口参数：	dataPtr：平台返回的数据
//
//	返回参数：	无
//
//	说明：		
//==========================================================
void OneNet_RevPro(unsigned char *cmd)
{
	
	char *req_payload = NULL;
	char *cmdid_topic = NULL;
	
	unsigned short topic_len = 0;
	unsigned short req_len = 0;
	
	unsigned char qos = 0;
	static unsigned short pkt_id = 0;
	
	unsigned char type = 0;
	
	short result = 0;

	char *dataPtr = NULL;
	char numBuf[10];
	int num = 0;
	cJSON *raw_json,*params_json,*humi_json,*light_json;
	type = MQTT_UnPacketRecv(cmd);
	switch(type)
	{
		case MQTT_PKT_PUBLISH:																//ޓ˕քPublishлϢ
		
			result = MQTT_UnPacketPublish(cmd, &cmdid_topic, &topic_len, &req_payload, &req_len, &qos, &pkt_id);
			if(result == 0)
			{
				char *data_ptr=NULL;
				printf("topic:%s, topic_len:%d, payload:%s, payload_len:%d\r\n",cmdid_topic,topic_len,req_payload,req_len);
				raw_json=cJSON_Parse(req_payload);
				params_json=cJSON_GetObjectItem(raw_json,"params");
				humi_json=cJSON_GetObjectItem(params_json,"humi2");
				if(humi_json!=0)
				{
					humi_max=humi_json->valueint;
				}
				
				light_json=cJSON_GetObjectItem(params_json,"val2");
				if(light_json!=0)
					light_max=light_json->valueint;
//					  OLED_ShowString(3, 1, "humi_max");
//       OLED_ShowNum(3, 9, humi_max, 2);			
//	   OLED_ShowString(4, 1, "temp_max");	
//	   OLED_ShowNum(4, 9, temp_max, 3);	
			
				
//				char *data_ptr=NULL;
//				data_ptr=strstr(cmdid_topic,"set/");
//				if(data_ptr)
//				{
//					char topic_buf[80],cmdid[40];
//					
//					data_ptr=strchr(data_ptr,'/');
//					data_ptr++;
//					
//					memcpy(cmdid_topic,data_ptr,36);
//					cmdid[36]=0;
//					snprintf(topic_buf,sizeof(topic_buf),"$sys/%s/%s/cmd/response/%s",PROID,DEVID,cmdid);
//					OneNET_Publish(topic_buf,"success");
//				}
				
//				root  = cJSON_Parse(req_payload);
//				if (root == NULL) {
//					printf("Error parsing JSON: %s\n", cJSON_GetErrorPtr());
//					return ;
//				}
//				params  = cJSON_GetObjectItem(root,"params");
//				if (params == NULL) {
//					printf("Error: \"params\" field not found or not an object.\n");
//					cJSON_Delete(root);
//					return ;
//				}
//				temperature = cJSON_GetObjectItem(params,"temp");
//				if (temperature != NULL) {
//					printf("Tempeature = %d\r\n",temperature->valueint);
//				}
//				humidity = cJSON_GetObjectItem(params,"humi");
//				if (humidity != NULL) {
//					printf("humidity = %d\r\n",humidity->valueint);
//				}
				
				
				
				cJSON_Delete(raw_json);	
			}
		break;
			
		case MQTT_PKT_PUBACK:														//ע̍PublishлϢìƽ̨ܘشքAck
		
			if(MQTT_UnPacketPublishAck(cmd) == 0)
//				UsartPrintf(USART_DEBUG, "Tips:	MQTT Publish Send OK\r\n");
			
		break;
		
		case MQTT_PKT_SUBACK:																//ע̍SubscribeлϢքAck
		
			if(MQTT_UnPacketSubscribe(cmd) == 0)
				;
//				UsartPrintf(USART_DEBUG, "Tips:	MQTT Subscribe OK\r\n");
		
		break;
		
		default:
			result = -1;
		break;
	}
	
	ESP8266_Clear();
	
	if(result == -1)
		return;

	if(type == MQTT_PKT_CMD || type == MQTT_PKT_PUBLISH)
	{
		MQTT_FreeBuffer(cmdid_topic);
		MQTT_FreeBuffer(req_payload);
	}

}
void OneNET_Publish(const char *topic, const char *msg)
{

	MQTT_PACKET_STRUCTURE mqtt_packet = {NULL, 0, 0, 0};			/* 协议包 */
	
	//UsartPrintf(USART_DEBUG, "Publish Topic: %s, Msg: %s\r\n", topic, msg);
	
	if(MQTT_PacketPublish(MQTT_PUBLISH_ID, topic, msg, strlen(msg), MQTT_QOS_LEVEL0, 0, 1, &mqtt_packet) == 0)
	{
		ESP8266_SendData(mqtt_packet._data, mqtt_packet._len);		/* 向平台发送订阅请求 */
		
		MQTT_DeleteBuffer(&mqtt_packet);				/* 删包 */
	}

}


void OneNET_Subscribe(void)
{
	
	MQTT_PACKET_STRUCTURE mqtt_packet = {NULL, 0, 0, 0};			/* 协议包 */
	
	char topic_buf[56];
	const char *topic = topic_buf;
	
	//订阅relay主题
	snprintf(topic_buf, sizeof(topic_buf), "$sys/%s/%s/thing/property/set", PROID, DEVID);
	
	printf("Subscribe1 Topic: %s\r\n", topic_buf);
	
	if(MQTT_PacketSubscribe(MQTT_SUBSCRIBE_ID, MQTT_QOS_LEVEL0, &topic, 1, &mqtt_packet) == 0)
	{
		ESP8266_SendData(mqtt_packet._data, mqtt_packet._len);		/* 向平台发送订阅请求 */
		
		MQTT_DeleteBuffer(&mqtt_packet);				/* 删包 */
	}
	
	//订阅set主题
//	memset(topic_buf,0,sizeof(topic_buf));
//	
//	snprintf(topic_buf, sizeof(topic_buf), "$sys/%s/%s/thing/property/set_reply", PROID, DEVID);
//	
//	printf("Subscribe2 Topic: %s\r\n", topic_buf);
//	
//	if(MQTT_PacketSubscribe(MQTT_SUBSCRIBE_ID, MQTT_QOS_LEVEL0, &topic, 1, &mqtt_packet) == 0)
//	{
//		ESP8266_SendData(mqtt_packet._data, mqtt_packet._len);		/* 向平台发送订阅请求 */
//		
//		MQTT_DeleteBuffer(&mqtt_packet);	/* 删包 */
//	}
	
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	
		if(huart == &huart2)//esp8266接收云平台数数据
		{
			if(esp8266_cnt >= sizeof(esp8266_buf))
			{            
				esp8266_cnt = 0; //防止串口被刷爿
			}
			esp8266_buf[esp8266_cnt++] = Uart2_RxData;

			HAL_UART_Receive_IT(&huart2,(uint8_t *)&Uart2_RxData, 1);
		}
		
}